import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Patch,
  Body,
  Param,
  Query,
  UseGuards,
  UseInterceptors,
  UploadedFile,
  HttpCode,
  HttpStatus
} from '@nestjs/common'
import { FileInterceptor } from '@nestjs/platform-express'
import { ApiTags, ApiOperation, ApiConsumes } from '@nestjs/swagger'
import { UserService } from './user.service'
import {
  CreateUserDto,
  UpdateUserDto,
  QueryUserDto,
  UserResponseDto,
  ChangePasswordDto,
  UserStatsDto,
  BulkUserOperationDto
} from '../../common/dto/user.dto'
import { PaginationResponseDto } from '../../common/dto/base.dto'
import { JwtAuthGuard, RolesGuard, PermissionsGuard } from '../../common/guards/auth.guard'
import {
  Roles,
  Permissions,
  Auth,
  ContentAuth,
  SystemAuth,
  UserRole,
  Permission
} from '../../common/decorators/auth.decorator'
import { CurrentUser, UserId } from '../../common/decorators/user.decorator'
import type { UserInfo } from '../../common/decorators/user.decorator'
import {
  ApiDoc,
  ApiPagination,
  ApiCreate,
  ApiUpdate,
  ApiDelete,
  ApiFindOne,
  ApiBatch,
  ApiUpload,
  ApiStats
} from '../../common/decorators/api.decorator'
import { ResponseMessage, Cache } from '../../common/decorators/response.decorator'
import { FileValidationPipe } from '../../common/pipes/validation.pipe'
import { Logger } from '@nestjs/common'

@ApiTags('用户管理')
@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard, PermissionsGuard)
export class UserController {
  private readonly logger = new Logger(UserController.name)

  constructor(private readonly userService: UserService) {}

  @Post()
  @SystemAuth.UserManage()
  @ApiCreate(Object, '创建用户', '创建新的用户账户')
  @ResponseMessage('用户创建成功')
  async create(@Body() createUserDto: CreateUserDto, @CurrentUser() currentUser: UserInfo): Promise<UserResponseDto> {
    this.logger.log('创建用户请求', {
      operator: currentUser.id,
      data: { ...createUserDto, password: '[HIDDEN]' }
    })

    const user = await this.userService.create(createUserDto, currentUser.id)

    this.logger.log('用户创建成功', {
      operator: currentUser.id,
      userId: user.id,
      username: user.username
    })

    return user as any
  }

  @Get()
  @ContentAuth.ArticleManage()
  @ApiPagination(Object, '获取用户列表', '分页获取用户列表')
  @Cache(300) // 缓存5分钟
  async findAll(
    @Query() queryDto: QueryUserDto,
    @CurrentUser() currentUser: UserInfo
  ): Promise<PaginationResponseDto<UserResponseDto>> {
    this.logger.debug('获取用户列表请求', {
      operator: currentUser.id,
      query: queryDto
    })

    return this.userService.findAll(queryDto, currentUser)
  }

  @Get('profile')
  @ApiDoc({
    summary: '获取当前用户信息',
    description: '获取当前登录用户的详细信息'
  })
  @Cache(60) // 缓存1分钟
  async getProfile(@CurrentUser() currentUser: UserInfo): Promise<UserResponseDto> {
    this.logger.debug('获取用户资料请求', {
      userId: currentUser.id
    })

    return this.userService.findById(currentUser.id, currentUser)
  }

  @Put('profile')
  @ApiUpdate(Object, '更新用户资料', '更新当前用户的个人资料')
  @ResponseMessage('用户资料更新成功')
  async updateProfile(
    @Body() updateUserDto: UpdateUserDto,
    @CurrentUser() currentUser: UserInfo
  ): Promise<UserResponseDto> {
    this.logger.log('更新用户资料请求', {
      userId: currentUser.id,
      data: updateUserDto
    })

    const user = await this.userService.update(currentUser.id, updateUserDto, currentUser.id)

    this.logger.log('用户资料更新成功', {
      userId: currentUser.id,
      updatedFields: Object.keys(updateUserDto)
    })

    return user as any
  }

  @Post('profile/avatar')
  @UseInterceptors(FileInterceptor('avatar'))
  @ApiUpload('上传头像', '上传用户头像图片')
  @ApiConsumes('multipart/form-data')
  @ResponseMessage('头像上传成功')
  async uploadAvatar(
    @UploadedFile()
    file: Express.Multer.File,
    @CurrentUser() currentUser: UserInfo
  ): Promise<{ avatarUrl: string }> {
    this.logger.log('上传头像请求', {
      userId: currentUser.id,
      filename: file.originalname,
      fileSize: file.size,
      mimeType: file.mimetype
    })

    const avatarUrl = await this.userService.uploadAvatar(currentUser.id, file)

    this.logger.log('头像上传成功', {
      userId: currentUser.id,
      avatarUrl
    })

    return { avatarUrl }
  }

  @Patch('change-password')
  @ApiDoc({
    summary: '修改密码',
    description: '修改当前用户的登录密码'
  })
  @HttpCode(HttpStatus.NO_CONTENT)
  @ResponseMessage('密码修改成功')
  async changePassword(
    @Body() changePasswordDto: ChangePasswordDto,
    @CurrentUser() currentUser: UserInfo
  ): Promise<void> {
    this.logger.log('修改密码请求', {
      userId: currentUser.id
    })

    await this.userService.changePassword(
      currentUser.id,
      changePasswordDto.currentPassword,
      changePasswordDto.newPassword
    )

    this.logger.log('密码修改成功', {
      userId: currentUser.id
    })
  }

  @Get('stats')
  @SystemAuth.UserManage()
  @ApiStats('获取用户统计', '获取用户相关的统计数据')
  @Cache(600) // 缓存10分钟
  async getStats(@CurrentUser() currentUser: UserInfo): Promise<UserStatsDto> {
    this.logger.debug('获取用户统计请求', {
      operator: currentUser.id
    })

    return this.userService.getStats()
  }

  @Get(':id')
  @SystemAuth.UserManage()
  @ApiFindOne(Object, '获取用户详情', '根据ID获取用户详细信息')
  @Cache(300) // 缓存5分钟
  async findOne(@Param('id') id: string, @CurrentUser() currentUser: UserInfo): Promise<UserResponseDto> {
    this.logger.debug('获取用户详情请求', {
      operator: currentUser.id,
      targetUserId: id
    })

    return this.userService.findById(id, currentUser)
  }

  @Put(':id')
  @SystemAuth.UserManage()
  @ApiUpdate(Object, '更新用户信息', '更新指定用户的信息')
  @ResponseMessage('用户信息更新成功')
  async update(
    @Param('id') id: string,
    @Body() updateUserDto: UpdateUserDto,
    @CurrentUser() currentUser: UserInfo
  ): Promise<UserResponseDto> {
    this.logger.log('更新用户信息请求', {
      operator: currentUser.id,
      targetUserId: id,
      data: updateUserDto
    })

    const user = await this.userService.update(id, updateUserDto, currentUser.id)

    this.logger.log('用户信息更新成功', {
      operator: currentUser.id,
      targetUserId: id,
      updatedFields: Object.keys(updateUserDto)
    })

    return user as any
  }

  @Delete(':id')
  @SystemAuth.UserManage()
  @ApiDelete('删除用户', '删除指定的用户账户')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ResponseMessage('用户删除成功')
  async remove(@Param('id') id: string, @CurrentUser() currentUser: UserInfo): Promise<void> {
    this.logger.log('删除用户请求', {
      operator: currentUser.id,
      targetUserId: id
    })

    await this.userService.remove(id, currentUser.id)

    this.logger.log('用户删除成功', {
      operator: currentUser.id,
      targetUserId: id
    })
  }

  @Patch(':id/status')
  @SystemAuth.UserManage()
  @ApiDoc({
    summary: '更新用户状态',
    description: '激活、禁用或锁定用户账户'
  })
  @ResponseMessage('用户状态更新成功')
  async updateStatus(
    @Param('id') id: string,
    @Body('status') status: 'active' | 'inactive' | 'locked',
    @CurrentUser() currentUser: UserInfo
  ): Promise<UserResponseDto> {
    this.logger.log('更新用户状态请求', {
      operator: currentUser.id,
      targetUserId: id,
      newStatus: status
    })

    const isActive = status === 'active'
    const user = await this.userService.updateStatus(id, isActive, currentUser.id)

    this.logger.log('用户状态更新成功', {
      operator: currentUser.id,
      targetUserId: id,
      newStatus: status
    })

    return user as any
  }

  @Post('batch')
  @SystemAuth.UserManage()
  @ApiBatch('批量操作用户', '批量创建、更新或删除用户')
  @ResponseMessage('批量操作完成')
  async batchOperation(
    @Body() batchDto: BulkUserOperationDto,
    @CurrentUser() currentUser: UserInfo
  ): Promise<{
    success: number
    failed: number
    errors: Array<{ index: number; error: string }>
  }> {
    this.logger.log('批量操作用户请求', {
      operator: currentUser.id,
      operation: batchDto.operation,
      count: batchDto.items.length
    })

    const result = await this.userService.batchOperation(batchDto, currentUser.id)

    this.logger.log('批量操作用户完成', {
      operator: currentUser.id,
      operation: batchDto.operation,
      success: result.summary?.success || 0,
      failed: result.summary?.failed || 0
    })

    return {
      success: result.summary?.success || 0,
      failed: result.summary?.failed || 0,
      errors: []
    }
  }

  @Get(':id/activities')
  @SystemAuth.UserManage()
  @ApiDoc({
    summary: '获取用户活动记录',
    description: '获取用户的操作活动记录'
  })
  @Cache(60) // 缓存1分钟
  async getUserActivities(
    @Param('id') id: string,
    @Query('page') page: number = 1,
    @Query('limit') limit: number = 20,
    @CurrentUser() currentUser: UserInfo
  ): Promise<PaginationResponseDto<any>> {
    this.logger.debug('获取用户活动记录请求', {
      operator: currentUser.id,
      targetUserId: id,
      page,
      limit
    })

    const result = await this.userService.getUserActivities(id, { page, limit }, currentUser)
    return {
      data: result.activities,
      total: result.pagination.total,
      page: result.pagination.page,
      limit: result.pagination.limit,
      totalPages: result.pagination.pages,
      hasNext: result.pagination.page < result.pagination.pages,
      hasPrev: result.pagination.page > 1
    }
  }

  @Post(':id/reset-password')
  @SystemAuth.UserManage()
  @ApiDoc({
    summary: '重置用户密码',
    description: '管理员重置指定用户的密码'
  })
  @ResponseMessage('密码重置成功')
  async resetPassword(
    @Param('id') id: string,
    @Body('newPassword') newPassword: string,
    @CurrentUser() currentUser: UserInfo
  ): Promise<{ temporaryPassword: string }> {
    this.logger.log('重置用户密码请求', {
      operator: currentUser.id,
      targetUserId: id
    })

    const result = await this.userService.resetPassword(id, currentUser.id)

    this.logger.log('用户密码重置成功', {
      operator: currentUser.id,
      targetUserId: id
    })

    return {
      temporaryPassword: result.defaultPassword
    }
  }

  @Get(':id/permissions')
  @SystemAuth.UserManage()
  @ApiDoc({
    summary: '获取用户权限',
    description: '获取用户的详细权限信息'
  })
  @Cache(300) // 缓存5分钟
  async getUserPermissions(
    @Param('id') id: string,
    @CurrentUser() currentUser: UserInfo
  ): Promise<{
    role: UserRole
    permissions: Permission[]
    inheritedPermissions: Permission[]
    customPermissions: Permission[]
  }> {
    this.logger.debug('获取用户权限请求', {
      operator: currentUser.id,
      targetUserId: id
    })

    const result = await this.userService.getUserPermissions(id, currentUser.id)
    return {
      role: result.user.role as any,
      permissions: result.permissions as any,
      inheritedPermissions: [] as any,
      customPermissions: [] as any
    }
  }

  @Put(':id/permissions')
  @SystemAuth.UserManage()
  @ApiDoc({
    summary: '更新用户权限',
    description: '更新用户的自定义权限'
  })
  @ResponseMessage('用户权限更新成功')
  async updateUserPermissions(
    @Param('id') id: string,
    @Body('permissions') permissions: Permission[],
    @CurrentUser() currentUser: UserInfo
  ): Promise<UserResponseDto> {
    this.logger.log('更新用户权限请求', {
      operator: currentUser.id,
      targetUserId: id,
      permissions
    })

    const result = await this.userService.updatePermissions(id, permissions, currentUser.id)

    this.logger.log('用户权限更新成功', {
      operator: currentUser.id,
      targetUserId: id,
      permissions
    })

    return {
      id: result.user.id,
      username: result.user.username,
      role: result.user.role as UserRole
    } as any
  }

  @Post('export')
  @SystemAuth.UserManage()
  @ApiDoc({
    summary: '导出用户数据',
    description: '导出用户数据为Excel或CSV格式'
  })
  @ResponseMessage('用户数据导出成功')
  async exportUsers(
    @Body() exportDto: { format: 'excel' | 'csv'; filters?: QueryUserDto },
    @CurrentUser() currentUser: UserInfo
  ): Promise<{
    data: Array<{
      ID: string
      用户名: string
      邮箱: string
      角色: any
      状态: string
      创建时间: string
      最后登录: string
    }>
    format: any
    count: number
    exportedAt: Date
  }> {
    this.logger.log('导出用户数据请求', {
      operator: currentUser.id,
      format: exportDto.format,
      filters: exportDto.filters
    })

    const result = await this.userService.exportUsers(exportDto, currentUser.id)

    this.logger.log('用户数据导出成功', {
      operator: currentUser.id,
      count: result.count
    })

    return result
  }

  @Post('import')
  @UseInterceptors(FileInterceptor('file'))
  @SystemAuth.UserManage()
  @ApiUpload('导入用户数据', '从Excel或CSV文件导入用户数据')
  @ApiConsumes('multipart/form-data')
  @ResponseMessage('用户数据导入完成')
  async importUsers(
    @UploadedFile()
    file: Express.Multer.File,
    @CurrentUser() currentUser: UserInfo
  ): Promise<{
    message: string
    results: {
      success: number
      failed: number
      errors: string[]
    }
    importedAt: Date
  }> {
    this.logger.log('导入用户数据请求', {
      operator: currentUser.id,
      filename: file.originalname,
      fileSize: file.size
    })

    const result = await this.userService.importUsers(file, currentUser.id)

    this.logger.log('用户数据导入完成', {
      operator: currentUser.id,
      success: result.results.success,
      failed: result.results.failed
    })

    return result
  }
}
